home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java Programmer's Toolkit
/
Java Programmer's Toolkit.iso
/
applets
/
collectn
/
incrseq.jav
< prev
next >
Wrap
Text File
|
1995-12-14
|
8KB
|
305 lines
/*
File: IncrSeq.java
Originally written by Doug Lea and released into the public domain.
Thanks for the assistance and support of Sun Microsystems Labs, Agorics
Inc, Loral, and everyone contributing, testing, and using this code.
History:
Date Who What
24Sep95 dl@cs.oswego.edu Create from collections.java working file
13Oct95 dl Changed to use accessOnly
*/
package collections;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
*
* Implementation of Immutable Seq
* @author Doug Lea
* @version 0.93
*
* <P> For an introduction to this package see <A HREF="index.html"> Overview </A>.
**/
public final class IncrSeq extends IncrImpl implements Seq {
private int indexArg_;
/**
* Make a new pure Seq using the default underlying Seq implementation
**/
public IncrSeq() { this(DefaultImplementations.seq()); }
/**
* Make a pure seq managing the given updatable seq s.
* Warning: Do not modify s during the the lifetime of the constructed pure seq!
**/
public IncrSeq(UpdatableSeq s) { super(s); indexArg_ = 0; }
/**
* Make a copy. Uses lazy update.
**/
protected Object clone() throws CloneNotSupportedException {
undelta();
IncrSeq s = new IncrSeq((UpdatableSeq)(updatable_));
nextVersion_ = s;
updatable_ = null;
op_ = NO_EDIT;
return s;
}
/**
* Implements collections.Seq.at.
* @see collections.Seq#at
**/
public synchronized Object at(int index)
throws NoSuchElementException {
return ((UpdatableSeq)(accessOnly())).at(index);
}
/**
* Implements collections.Seq.first.
* @see collections.Seq#first
**/
public synchronized Object first()
throws NoSuchElementException {
return ((UpdatableSeq)(accessOnly())).first();
}
/**
* Implements collections.Seq.last.
* @see collections.Seq#last
**/
public synchronized Object last()
throws NoSuchElementException {
return ((UpdatableSeq)(accessOnly())).last();
}
/**
* Implements collections.Seq.firstIndexOf.
* @see collections.Seq#firstIndexOf
**/
public synchronized int firstIndexOf(Object element, int startingIndex) {
return ((UpdatableSeq)(accessOnly())).firstIndexOf(element, startingIndex);
}
/**
* Implements collections.Seq.firstIndexOf.
* @see collections.Seq#firstIndexOf
**/
public synchronized int firstIndexOf(Object element) {
return ((UpdatableSeq)(accessOnly())).firstIndexOf(element);
}
/**
* Implements collections.Seq.lastIndexOf.
* @see collections.Seq#lastIndexOf
**/
public synchronized int lastIndexOf(Object element, int startingIndex) {
return ((UpdatableSeq)(accessOnly())).lastIndexOf(element, startingIndex);
}
/**
* Implements collections.Seq.lastIndexOf.
* @see collections.Seq#lastIndexOf
**/
public synchronized int lastIndexOf(Object element) {
return ((UpdatableSeq)(accessOnly())).lastIndexOf(element);
}
/**
* Implements collections.Seq.subseq.
* Makes a full new Seq, not a lazy update.
* @see collections.Seq#subseq
**/
public synchronized /* IncrSeq */ Seq subseq(int index, int length)
throws NoSuchElementException {
return new IncrSeq(((UpdatableSeq)(((UpdatableSeq)accessOnly()).subseq(index, length))));
}
/**
* Implements collections.Collection.removingOneOf
* @see collections.Collection#removingOneOf
**/
public synchronized /* IncrSeq */ Collection removingOneOf(Object element) {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
int idx = u.firstIndexOf(element);
if (idx < 0)
return this;
else {
try {
u.removeAt(idx);
}
catch (NoSuchElementException ex) {} // can't happen
IncrSeq s = new IncrSeq(u);
nextVersion_ = s;
updatable_ = null;
firstObjectArg_ = element;
indexArg_ = idx;
op_ = ADD_EDIT;
return s;
}
}
/**
* Implements collections.Collection.excluding.
* If more than one occurrence of element exists, it makes
* a full, non-lazy copy.
* @see collections.Collection#excluding
**/
public synchronized /* IncrSeq */ Collection excluding(Object element) {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
int occ = u.occurrencesOf(element);
if (occ == 0)
return this;
else if (occ == 1)
return this.removingOneOf(element);
else {
UpdatableSeq c = (UpdatableSeq)(u.duplicate());
c.exclude(element);
return new IncrSeq(c);
}
}
/**
* Implements collections.Collection.replacingOneOf
* @see collections.Collection#replacingOneOf
**/
public synchronized /* IncrSeq */ Collection replacingOneOf(Object oldElement,
Object newElement)
throws IllegalElementException {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
int idx = u.firstIndexOf(oldElement);
if (idx < 0)
return this;
else {
try {
u.replaceAt(idx, newElement);
}
catch (NoSuchElementException ex) {} // can't happen
IncrSeq s = new IncrSeq(u);
nextVersion_ = s;
updatable_ = null;
firstObjectArg_ = oldElement;
op_ = REPLACE_EDIT;
indexArg_ = idx;
return s;
}
}
/**
* Implements collections.Collection.replacingAllOf.
* If more than one occurrence of element exists, it makes
* a full, non-lazy copy.
* @see collections.Collection#replacingAllOf
**/
public synchronized /* IncrSeq */ Collection replacingAllOf(Object oldElement,
Object newElement)
throws IllegalElementException {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
int oldocc = u.occurrencesOf(oldElement);
if (oldocc == 0)
return this;
else if (oldocc == 1)
return this.replacingOneOf(oldElement, newElement);
else {
UpdatableSeq c = (UpdatableSeq)(u.duplicate());
c.replaceAllOf(oldElement, newElement);
return new IncrSeq(c);
}
}
/**
* Implements collections.Seq.insertingAt.
* @see collections.Seq#insertingAt
**/
public synchronized /* IncrSeq */ Seq insertingAt(int index, Object element)
throws IllegalElementException, NoSuchElementException {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
u.insertAt(index, element);
IncrSeq s = new IncrSeq(u);
nextVersion_ = s;
updatable_ = null;
indexArg_ = index;
op_ = REMOVE_EDIT;
return s;
}
/**
* Implements collections.Seq.removingAt.
* @see collections.Seq#removingAt
**/
public synchronized /* IncrSeq */ Seq removingAt(int index)
throws NoSuchElementException {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
Object element = u.at(index);
u.removeAt(index);
IncrSeq s = new IncrSeq(u);
nextVersion_ = s;
updatable_ = null;
indexArg_ = index;
firstObjectArg_ = element;
op_ = ADD_EDIT;
return s;
}
/**
* Implements collections.Seq.replacingAt
* @see collections.Seq#replacingAt
**/
public synchronized /* IncrSeq */ Seq replacingAt(int index, Object element)
throws IllegalElementException, NoSuchElementException {
undelta();
UpdatableSeq u = (UpdatableSeq)updatable_;
Object oldElement = u.at(index);
if (oldElement.equals(element))
return this;
else {
u.replaceAt(index, element);
IncrSeq s = new IncrSeq(u);
nextVersion_ = s;
updatable_ = null;
indexArg_ = index;
firstObjectArg_ = oldElement;
op_ = REPLACE_EDIT;
return s;
}
}
/**
* Perform updates within an edit chain
**/
protected synchronized UpdatableCollection doEdit(UpdatableCollection c) {
UpdatableSeq u = (UpdatableSeq)c;
try {
if (op_ == ADD_EDIT)
u.insertAt(indexArg_, firstObjectArg_);
else if (op_ == REMOVE_EDIT)
u.removeAt(indexArg_);
else if (op_ == REPLACE_EDIT)
u.replaceAt(indexArg_, firstObjectArg_);
}
catch (IllegalElementException ex) {} // we've screened for all possible
catch (NoSuchElementException ex) {}
return u;
}
}